package com.googlecode.adaboost.classifier.point;

import java.util.Map;
import java.util.Vector;

import com.googlecode.adaboost.classifier.BinaryWeakClassifier;
import com.googlecode.adaboost.classifier.util.WeakClassifierEvaluator;
import com.googlecode.adaboost.exception.AdaBoostException;
import com.googlecode.adaboost.trainer.AdaBoostConfiguration;
import com.googlecode.adaboost.trainer.DataElement;
import com.googlecode.adaboost.trainer.TrainingData;

public class BinaryPointWeakClassifier extends BinaryWeakClassifier {

	private double value;
	private boolean decision;

	@Override
	public void initalize(AdaBoostConfiguration systemSettings,
			Map<String, String> moduleSettings) throws AdaBoostException {

	}

	@Override
	public void initClassifier(TrainingData trainingData, double[] probability) {
		Vector<DataElement> data = trainingData.getTrainingData();
		int num = data.size();
		double bestValue;
		boolean bestDecision;
		double minErrRate = 0.0;
		double errRate = 0.0;
		value = data.get(0).getInput().get(0) - 1;
		bestValue = value;
		decision = true;
		bestDecision = decision;
		minErrRate = WeakClassifierEvaluator.evaluateBinaryClassifier(this,
				trainingData, probability);
		if (minErrRate > 0.5) {
			bestDecision = false;
			minErrRate = 1 - minErrRate;
		}
		for (int i = 0; i < num - 1; ++i) {
			while (i + 1 < num
					&& data.get(i + 1).getInput() == data.get(i).getInput()) {
				i++;
			}
			value = (data.get(i).getInput().get(0) + data.get(i + 1).getInput()
					.get(0)) * 0.5;
			errRate = WeakClassifierEvaluator.evaluateBinaryClassifier(this,
					trainingData, probability);
			if (errRate < minErrRate) {
				bestValue = value;
				bestDecision = true;
				minErrRate = errRate;
			} else if (1 - errRate < minErrRate) {
				bestValue = value;
				bestDecision = false;
				minErrRate = 1 - errRate;
			}
		}
		value = bestValue;
		decision = bestDecision;
	}

	@Override
	public int makeDecision(DataElement data) {
		if (this.decision && data.getInput().get(0) <= this.value
				|| !this.decision && data.getInput().get(0) >= this.value) {
			return -1;
		}
		return 1;
	}

	@Override
	public void dumpClassifier() {
		System.out
				.println("h = I(x" + (decision ? " > " : " < ") + value + ")");
		System.out.printf("alpha: %.6f\n", alpha);
	}

}
